package com.sibrary.booxoo.download;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import com.sibrary.utils.Constants;

import android.os.Environment;
import android.os.Message;
import android.os.StatFs;

class BooxooDownloadRunnable implements Runnable {

	private BooxooDownloadItem mItem;
	private BooxooDownloadController mController;
	private String mFilepath;

	private boolean abort; // 控制线程终止标志

	public BooxooDownloadRunnable(BooxooDownloadItem item) {
		mItem = item;
		mController = BooxooDownloadController.getInstance();

		mFilepath = Environment.getExternalStorageDirectory().getPath()
				+ "/Downloads/";
		createFilePath(mFilepath);

		abort = false;
	}

	public void run() {
		try {
			downloadFile();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 文件下载
	 */
	public void downloadFile() throws IOException {
		InputStream inputStream;
		FileOutputStream fileOs;

		String replyHeader;
		int fileSize;

		byte buf[] = new byte[4096];
		int downloadFilePos = 0;
		int numRead = 0;

		double oldProgress = 0.0;
		double newProgress = 0.0;

		File downloadFile = new File(mFilepath + mItem.getFilename());
		if (downloadFile != null && downloadFile.exists()) {
			downloadFile.delete();
		}

		URL Url = new URL(mItem.getUrl());
		URLConnection conn = Url.openConnection();
		conn.connect();

		replyHeader = conn.getHeaderField("Content-Disposition");
		if (replyHeader != null) {
			reCheckFilename(replyHeader);
		}

		inputStream = conn.getInputStream();
		if (inputStream == null) {
			throw new RuntimeException("File can not to be get!");
		}

		// 根据响应获取文件大小
		fileSize = conn.getContentLength();
		if (fileSize < 0) {
			throw new RuntimeException("File size can not be informed!");
		}

		if (fileSize > getSDCardSize()) {
			inputStream.close();
			sendMessage(Constants.MESSAGE_DOWNLOAD_NO_SPACE, mItem);
			return;
		}

		fileOs = new FileOutputStream(downloadFile);
		sendMessage(Constants.MESSAGE_DOWNLOAD_START, mItem);

		while (!abort && (numRead = inputStream.read(buf)) != -1) {
			fileOs.write(buf, 0, numRead);
			downloadFilePos += numRead;

			newProgress = downloadFilePos * 100f / fileSize;
			if (newProgress > oldProgress + 5) {
				mItem.setProgress((int) newProgress);
				oldProgress = newProgress;

				sendMessage(Constants.MESSAGE_DOWNLOAD_RUNNING, mItem);
			}
		}

		if (!abort) {
			sendMessage(Constants.MESSAGE_DOWNLOAD_SUCCESSFUL, mItem);
			sendMessage(Constants.MESSAGE_DOWNLOAD_FINISH, mItem);
		} else {
			sendMessage(Constants.MESSAGE_DOWNLOAD_FAILED, mItem);
			sendMessage(Constants.MESSAGE_DOWNLOAD_CANCEL, mItem);
		}

		try {
			inputStream.close();
		} catch (Exception e) {
			sendMessage(Constants.MESSAGE_DOWNLOAD_FAILED, mItem);
			e.printStackTrace();
		}

		if (abort && downloadFile.exists()) {
			downloadFile.delete();
		}
	}

	/**
	 * 重新检查文件名
	 */
	private void reCheckFilename(String replyHeader) {
		replyHeader = replyHeader.toLowerCase();
		int index = replyHeader.indexOf("filename");

		if (index != -1) {
			String name = replyHeader.substring(
					index + "filename".length() + 1, replyHeader.length());

			name = name.replace("'", "").replace("\"", "");
			mItem.setFilename(name);
		}
	}

	/**
	 * 发送消息
	 */
	private void sendMessage(final int msg, Object obj) {
		Message m = new Message();
		m.what = msg;
		m.obj = obj;
		mController.mHandler.sendMessage(m);
	}

	/**
	 * 检查sdcard可用大小
	 */
	private long getSDCardSize() {
		File sdcardPath = Environment.getExternalStorageDirectory();
		StatFs statfs = new StatFs(sdcardPath.getPath());
		return ((long) statfs.getAvailableBlocks() * (long) statfs
				.getBlockSize());
	}

	/**
	 * 终止线程
	 */
	public void AbortRunnable() {
		abort = true;
	}

	/**
	 * 创建目录
	 */
	private static void createFilePath(String path) {
		File file = new File(path);
		if (!file.exists()) {
			file.mkdir();
		}
	}
}
